/*    Copyright 2010 Tobias Marschall
 *
 *    This file is part of MoSDi.
 *
 *    MoSDi is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    MoSDi is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with MoSDi.  If not, see <http://www.gnu.org/licenses/>.
 */

package mosdi.subcommands;

import mosdi.fa.Alphabet;
import mosdi.util.IupacStringConstraints;
import mosdi.util.Log;
import mosdi.util.iterators.IupacPatternIterator;

public class IupacRangesSubcommand extends Subcommand {

	@Override
	public String usage() {
		return 
		super.usage()+" [options] <rangecount> <length>\n" +
		"Options:\n" +
		"  -m minimum number of 1-/2-/3-/4-valued letters, default: \"0,0,0,0\"\n" +
		"  -M maximum number of 1-/2-/3-/4-valued letters, default: \"<length>,0,0,0\"";
	}

	@Override
	public String description() {
		return "Splits a motif space into ranges.";
	}

	@Override
	public String name() {
		return "iupac-ranges";
	}

	@Override
	public int run(String[] args) {
		parseOptions(args, 2, "m:M:");

		// Option dependencies
		// -- none --

		// Mandatory arguments
		int rangeCount = getIntArgument(0);
		int length = getIntArgument(1);

		// Options
		int[] minFrequencies = {0,0,0,0};
		minFrequencies = getRangedIntTupleOption("m", 4, 0, length, minFrequencies);
		int[] maxFrequencies = {length,0,0,0};
		maxFrequencies = getRangedIntTupleOption("M", 4, 0, length, maxFrequencies);

		IupacStringConstraints constraints = new IupacStringConstraints(minFrequencies,maxFrequencies);
		long total = constraints.validStringCount(length);
		IupacPatternIterator iterator = new IupacPatternIterator(length, constraints);
		int[] last = iterator.next();
		total -= 1;
		Alphabet iupacAlphabet = Alphabet.getIupacAlphabet();
		for (;rangeCount>0; --rangeCount) {
			long skip = total/rangeCount;
			iterator.skipByNumber(skip-1);
			int[] s = iterator.next();
			total -= skip;
			if (rangeCount==1) {
				Log.printf(Log.Level.STANDARD,"%s\t%sA\n",iupacAlphabet.buildString(last), iupacAlphabet.buildString(s));	
			} else {
				Log.printf(Log.Level.STANDARD,"%s\t%s\n",iupacAlphabet.buildString(last), iupacAlphabet.buildString(s));	
			}
			last = s;
		}
		return 0;
	}

}
